﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace Elentok.Common.Wpf.Controls
{
  /// <summary>
  /// The HtmlBox is a bindable WebBrowser (see the <see cref="HtmlText"/>
  /// and <see cref="HtmlData"/> properties).
  /// </summary>
  public partial class HtmlBox : UserControl
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="HtmlBox"/> class
    /// </summary>
    public HtmlBox()
    {
      InitializeComponent();
    }

    /// <summary>
    /// The "HtmlText" dependency property
    /// </summary>
    public static readonly DependencyProperty HtmlTextProperty =
      DependencyProperty.Register("HtmlText", typeof(string), typeof(HtmlBox));

    /// <summary>
    /// The "HtmlData" dependency property
    /// </summary>
    public static readonly DependencyProperty HtmlDataProperty =
      DependencyProperty.Register("HtmlData", typeof(IArrayWrapper<byte>), typeof(HtmlBox));

    /// <summary>
    /// Gets or sets the html (in text format) that is displayed in the web browser
    /// </summary>
    public string HtmlText
    {
      get
      {
        return (string)GetValue(HtmlTextProperty);
      }
      set
      {
        SetValue(HtmlTextProperty, value);
      }
    }

    /// <summary>
    /// Gets or sets the html (in bytes format) that is displayed in the web browser
    /// (The reason for the IArrayWrapper is that you cannot databind normal arrays)
    /// </summary>
    public IArrayWrapper<byte> HtmlData
    {
      get
      {
        return (IArrayWrapper<byte>)GetValue(HtmlDataProperty);
      }
      set
      {
        SetValue(HtmlDataProperty, value);
      }
    }

    /// <summary>
    /// Invoked whenever the effective value of any dependency property on
    /// this System.Windows.FrameworkElement has been updated.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
      base.OnPropertyChanged(e);
      if (e.Property == HtmlTextProperty)
        UpdateFromHtmlText();
      else if (e.Property == HtmlDataProperty)
        UpdateFromHtmlData();
    }

    #region Helper Methods

    private void UpdateFromHtmlText()
    {
      if (!string.IsNullOrEmpty(HtmlText))
        browser.NavigateToString(HtmlText);
      else
        Clear();
    }

    private void UpdateFromHtmlData()
    {
      if (HtmlData != null)
      {
        MemoryStream stream = new MemoryStream(HtmlData.ToArray());
        browser.NavigateToStream(stream);
      }
      else
        Clear();
    }

    private void Clear()
    {
      browser.NavigateToString("<html></html>");
    }

    #endregion
  }
}
